﻿namespace NorthernLights.Controls
{
    using System;
    using System.ComponentModel;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    /// <summary>
    /// Notification class.
    /// </summary>
    public partial class Notification : UserControl, INotifyPropertyChanged
    {
        #region Fields
        private BackgroundWorker bg = new BackgroundWorker();
        private string message;
        private Brush color;
        private Action action;
        private bool previousStateSystemTray;
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the Notification class.
        /// </summary>
        public Notification()
        {
            InitializeComponent();

            this.DataContext = this;

            this.bg.WorkerSupportsCancellation = true;
        }
        #endregion

        #region Events
        /// <summary>
        /// PropertyChanged event.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the message to display.
        /// </summary>
        public string Message
        {
            get
            {
                return this.message;
            }

            set
            {
                this.message = value;
                this.NotifyPropertyChanged("Message");
            }
        }

        /// <summary>
        /// Gets or sets the background color.
        /// </summary>
        public Brush Color
        {
            get
            {
                return this.color;
            }

            set
            {
                this.color = value;
                this.NotifyPropertyChanged("Color");
            }
        }

        /// <summary>
        /// Gets a value indicating whether the Notification is busy.
        /// </summary>
        public bool IsBusy { get; private set; }
        #endregion

        #region Public methods
        /// <summary>
        /// Show the notification.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="background">The background color.</param>
        /// <param name="onTap">The onTap action.</param>
        public void Show(string message, Brush background, Action onTap)
        {
            if (!this.IsBusy)
            {
                this.IsBusy = true;

                this.previousStateSystemTray = Microsoft.Phone.Shell.SystemTray.IsVisible;

                this.Message = message;
                this.Color = background;
                this.action = onTap;

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    if (this.previousStateSystemTray)
                    {
                        Microsoft.Phone.Shell.SystemTray.IsVisible = false;
                    }

                    VisualStateManager.GoToState(this, "Enter", false);
                });
            }
        }
        #endregion

        #region Private methods
        private void EnterStoryboardCompleted(object sender, EventArgs e)
        {
            int seconds = 3;

            this.bg.DoWork += (sender2, e2) =>
                {
                    for (int count = 0; count < (4 * seconds); count++)
                    {
                        if (bg.CancellationPending)
                        {
                            e2.Cancel = true;
                            break;
                        }
                         
                        Thread.Sleep(250);
                    }
                };

            this.bg.RunWorkerCompleted += (sender3, e3) =>
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    VisualStateManager.GoToState(this, "Exit", false);

                    if (this.previousStateSystemTray)
                    {
                        Microsoft.Phone.Shell.SystemTray.IsVisible = true;
                    }
                });
            };

            this.bg.RunWorkerAsync();
        }

        private void ExitStoryboardCompleted(object sender, EventArgs e)
        {
            this.IsBusy = false;
        }

        private void OnTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            if (this.bg.IsBusy)
            {
                this.bg.CancelAsync();

                if (this.action != null)
                {
                    this.action();
                }
            }
        }

        private void NotifyPropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion
    }
}
